package utils;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.display.DisplayManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.os.SystemClock;
import android.text.format.Formatter;
import android.view.Display;

import androidx.core.app.ActivityCompat;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
//import android.os.SystemProperties;

public class DevInfoUtil {
    /*
     *  系统信息
     * */
    // 获取序列号
    public static String getSN() {
        String serial = "unKnown";
        try {
            Class clazz = Class.forName("android.os.Build");
            Class paraTypes = Class.forName("java.lang.String");
            Method method = clazz.getDeclaredMethod("getString", paraTypes);
            if (!method.isAccessible()) {
                method.setAccessible(true);
            }
            serial = (String) method.invoke(new Build(), "ro.serialno");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return serial;
    }

    // 设备型号
    public static String getModel() {
        return Build.MODEL;
    }

    // 设备品牌
    public static String getBrand() {
        return Build.BRAND;
    }

    // 安卓版本
    public static String getOsInfo() {
        return "Android " + Build.VERSION.RELEASE;
    }

    // 固件版本
    public static String getFingerPrint() {
        return Build.FINGERPRINT;
    }

    // CPU信息
    public static String getCpuInfo(String flag) {
        try {
            FileReader fr = new FileReader("/proc/cpuinfo");
            BufferedReader br = new BufferedReader(fr);
            String result = "";
            String text = "";
            while ((text = br.readLine()) != null) {
                if (flag.equals("Hardware")) {
                    if (text.indexOf("Hardware") >= 0) {
                        result = text.split(":")[1];
                    }
                } else {
                    result += text + "\n";
                }
            }
            if (result.equals("")) result = getModel();
            return result;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "unKnown";
    }

    // CPU架构
    public static String getCpuModel() {
        String[] abis = new String[]{};
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            abis = Build.SUPPORTED_ABIS;
        } else {
            abis = new String[]{Build.CPU_ABI, Build.CPU_ABI2};
        }
        StringBuilder abiStr = new StringBuilder();
        for (String abi : abis) {
            abiStr.append(abi);
            abiStr.append(';');
        }
        return abiStr.toString();
    }

    // RAM 获取运行内存的信息
    public static JSONObject getRAM(Context ctx) {
        JSONObject ram = new JSONObject();
        try {
            ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
            ActivityManager.MemoryInfo info = new ActivityManager.MemoryInfo();
            manager.getMemoryInfo(info);
            String t = fullMemory(Formatter.formatFileSize(ctx, info.totalMem));
            String a = Formatter.formatFileSize(ctx, info.availMem);
            ram.put("total", t);
            ram.put("avail", a);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ram;
    }

    // ROM 获取存储空间的信息
    public static JSONObject getROM(Context ctx) {
        JSONObject rom = new JSONObject();
        try {
            File path = Environment.getExternalStorageDirectory();
            StatFs stat = new StatFs(path.getPath());
            long blockSize = stat.getBlockSize();
            long totalBlocks = stat.getBlockCount();
            long availableBlocks = stat.getAvailableBlocks();
            String t = fullMemory(Formatter.formatFileSize(ctx, blockSize * totalBlocks));
            String a = Formatter.formatFileSize(ctx, blockSize * availableBlocks);
            rom.put("total", t);
            rom.put("avail", a);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return rom;
    }

    /*
     * 屏幕信息
     * */
    // 分辨率
    @SuppressLint("NewApi")
    public static JSONArray getScreenInfo(Context ctx) {
        JSONArray s = new JSONArray();
        try {
            DisplayManager mDisplayManager = (DisplayManager) ctx.getSystemService(Context.DISPLAY_SERVICE);
            Display[] displays = mDisplayManager.getDisplays();
            for (Display d : displays) {
                int id = d.getMode().getModeId();
                int w = d.getMode().getPhysicalWidth();
                int h = d.getMode().getPhysicalHeight();
//                JSONObject o = new JSONObject();
//                o.put("id", id);
//                o.put("width", w);
//                o.put("height", h);
                s.put(w+"*"+h);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }

    /*
     * 网络类型
     * */
    @SuppressLint("MissingPermission")
    public static JSONArray getNetworkType(Context ctx) {
        JSONArray s = new JSONArray();
        try {
            final NetworkInfo nf = ((ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE)).getActiveNetworkInfo();
            String net = nf.getTypeName();
            JSONObject o = new JSONObject();
            o.put("type", net);
            o.put("mac", net.equals("WIFI") || nf.getType() == 1 ? getWlanMac(ctx) : nf.getExtraInfo());
            o.put("sub", nf.getSubtypeName());
            s.put(o);
//            if (net.equals("Mobile") || nf.getType() == 0) {}
//            if (net.equals("WIFI") || nf.getType() == 1) {}
//            if (net.equals("Ethernet") || nf.getType() == 9) {}
        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }

    // 获取wlan mac
    @SuppressLint({"HardwareIds", "MissingPermission"})
    public static String getWlanMac(Context ctx) {
        try {
            WifiManager wifi = (WifiManager) ctx.getSystemService(Context.WIFI_SERVICE);
            WifiInfo info = wifi.getConnectionInfo();
            //MyUtil.showLog("getWlanMac","BSSID:"+info.getBSSID()+",wifi名:"+info.getSSID()+",连接速度:"+info.getLinkSpeed());
            return info.getMacAddress();
        } catch (Exception e) {
            return "unKnown";
        }
    }

    // 获取局域网ip地址
    public static JSONArray getLocalIP() {
        try {
            Enumeration nis = NetworkInterface.getNetworkInterfaces();
            InetAddress ia = null;
            String netType = "";
            String wlan = "{}";
            String eth = "{}";
            while (nis.hasMoreElements()) {
                NetworkInterface ni = (NetworkInterface) nis.nextElement();
                Enumeration<InetAddress> ias = ni.getInetAddresses();
                while (ias.hasMoreElements()) {
                    ia = ias.nextElement();
                    //MyUtil.showLog("getLocalIP",ia);
                    if (ia instanceof Inet6Address) {
                        if (String.valueOf(ia).indexOf("wlan") >= 0) {
                            netType = "wlan";
                            wlan = "{\"type\": \"WLAN\",\"ipv6\":" + "\"" + ia.getHostAddress().split("%")[0] + "\"";
                        }
                        if (String.valueOf(ia).indexOf("eth") >= 0) {
                            netType = "eth";
                            eth = "{\"type\": \"LAN\",\"ipv6\":" + "\"" + ia.getHostAddress().split("%")[0] + "\"";
                        }
                    } else {
                        if (netType.equals("wlan")) {
                            wlan = wlan + ",\"ipv4\":" + "\"" + ia.getHostAddress() + "\"}";
                        }
                        if (netType.equals("eth")) {
                            eth = eth + ",\"ipv4\":" + "\"" + ia.getHostAddress() + "\"}";
                        }
                        netType = "";
                    }
                }
            }
            return new JSONArray("[" + wlan + "," + eth + "]");
        } catch (SocketException | JSONException e) {
            e.printStackTrace();
            return new JSONArray();
        }
    }

    // 蓝牙设备信息
    @SuppressLint("MissingPermission")
    public static JSONObject getBleInfo(Context ctx) {
        String name = "unKnown";
        String mac = "unKnown";
        String version = "unKnown";
        JSONObject o = new JSONObject();
        BluetoothManager bm = (BluetoothManager) ctx.getSystemService(Context.BLUETOOTH_SERVICE);
        BluetoothAdapter ba = bm.getAdapter();

        PackageManager pm = ctx.getPackageManager();
        boolean isBT = pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
        boolean isBLE = pm.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
        if (ba != null && ba.isEnabled()) {
            if (Build.VERSION.SDK_INT >= 26 && ba.isLeExtendedAdvertisingSupported()) version = "Bluetooth 5.2 (BLE)";
            else if (Build.VERSION.SDK_INT >= 26 && ba.isLePeriodicAdvertisingSupported()) version = "Bluetooth 5.1 (BLE)";
            else if (ba.isMultipleAdvertisementSupported()) version = "Bluetooth 5.0 (BLE)";
            else if (ba.isOffloadedFilteringSupported()) version = "Bluetooth 4.1 (BLE)";
            else if (isBLE) version = "Bluetooth 4.0 (BLE)";
            else version = "Bluetooth 3.0 或 之前的版本";
        } else {
            version = "当前蓝牙未开启";
        }
        if (ActivityCompat.checkSelfPermission(ctx, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
            name = ba.getName();
            mac = ba.getAddress();
            MyUtil.showLog("BluetoothManager",name);
            MyUtil.showLog("BluetoothManager",mac);
        }
        try {
            BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
            if (bluetooth!=null) {
                name = bluetooth.getName();
                mac = bluetooth.getAddress();
            }
            MyUtil.showLog("BluetoothAdapter",name);
            MyUtil.showLog("BluetoothAdapter",mac);
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            name = name==null?"unKnown":name;
            o.put("name",name);
            mac = mac==null?"蓝牙未开启":mac;
            o.put("mac",mac);
            version = version==null?"蓝牙未开启":version;
            o.put("version",version);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return o;
    }

    private static String fullMemory(String s) {
        MyUtil.showLog("fullMemory",s);
        String num = "0",unit=" GB";
        try {
            num = s.split(" ")[0];
            unit = s.split(" ")[1];
        } catch (Exception e) {
            e.printStackTrace();
        }
        Float fNum = Float.valueOf(num);
        if (Math.max(1, fNum) == Math.min(fNum, 3)) {
            s = 2+" "+unit;
        }
        if (Math.max(3, fNum) == Math.min(fNum, 5)) {
            s = 4+" "+unit;
        }
        if (Math.max(5, fNum) == Math.min(fNum, 9)) {
            s = 8+" "+unit;
        }
        if (Math.max(9, fNum) == Math.min(fNum, 17)) {
            s = 16+" "+unit;
        }
        if (Math.max(17, fNum) == Math.min(fNum, 33)) {
            s = 32+" "+unit;
        }
        if (Math.max(33, fNum) == Math.min(fNum, 65)) {
            s = 64+" "+unit;
        }
        if (Math.max(65, fNum) == Math.min(fNum, 129)) {
            s = 128+" "+unit;
        }
        if (Math.max(129, fNum) == Math.min(fNum, 257)) {
            s = 256+" "+unit;
        }
        if (Math.max(257, fNum) == Math.min(fNum, 513)) {
            s = 512+" "+unit;
        }
        MyUtil.showLog("fullMemory result",s);
        return s;
    }

    // cpu 频率
    public static String getMaxCpuFreq() {
        String result = "";
        ProcessBuilder cmd;
        try {
            String[] args = { "/system/bin/cat",
                    "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" };
            cmd = new ProcessBuilder(args);
            Process process = cmd.start();
            InputStream in = process.getInputStream();
            byte[] re = new byte[24];
            while (in.read(re) != -1) {
                result = result + new String(re);
            }
            in.close();
        } catch (IOException ex) {
            ex.printStackTrace();
            result = "N/A";
        }
        return result.trim();
    }

    // 获取CPU最小频率（单位KHZ）
    public static String getMinCpuFreq() {
        String result = "";
        ProcessBuilder cmd;
        try {
            String[] args = { "/system/bin/cat",
                    "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq" };
            cmd = new ProcessBuilder(args);
            Process process = cmd.start();
            InputStream in = process.getInputStream();
            byte[] re = new byte[24];
            while (in.read(re) != -1) {
                result = result + new String(re);
            }
            in.close();
        } catch (IOException ex) {
            ex.printStackTrace();
            result = "N/A";
        }
        return result.trim();
    }

    // 实时获取CPU当前频率（单位KHZ）
    public static String getCurCpuFreq() {
        String result = "N/A";
        try {
            FileReader fr = new FileReader(
                    "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq");
            BufferedReader br = new BufferedReader(fr);
            String text = br.readLine();
            result = text.trim();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    // 获取CPU名字
    public static String getCpuName() {
        try {
            FileReader fr = new FileReader("/proc/cpuinfo");
            BufferedReader br = new BufferedReader(fr);
            String text = br.readLine();
            String[] array = text.split(":\\s+", 2);
            for (int i = 0; i < array.length; i++) {
            }
            return array[1];
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}